# -*- coding: utf-8 -*-

import abc
import logging
import sys
import time

from component import Component


class Task(object):

    def __init__(self, cfg):
        self._cfg = cfg

        self._logger = logging.getLogger(cfg['logger_name'])

        self._components = {}
        if 'components' in cfg and type(cfg['components']) == list:
            for x in cfg['components']:
                self._components[x['name']] = Component.create(x['class_name'], {
                    'task_name': cfg['task_name'],
                    'task_full_name': cfg['task_full_name'],
                    'cfg': x['cfg']
                })
        if 'messenger' not in self._components.keys():
            self._components['messenger'] = Component.create('messenger.Messenger', {
                'task_name': cfg['task_name'],
                'task_full_name': cfg['task_full_name'],
                'cfg': {}
            })

        self._init()

    def _init(self):
        pass

    def end(self):
        try:
            self._end()

            for x in self._components.values():
                x.destroy()

            self._cfg = None
        except Exception as e:
            self._logger.warning('%s:end(): %s\n' % (self.__class__.__name__, e))

    def _end(self):
        pass

    @abc.abstractmethod
    def begin(self):
        raise NotImplementedError('call to abstract method %s.begin' % (self.__class__,))

    def _send_error_msg(self, msg, immediately_exit=True):
        self._logger.critical(msg)

        try:
            self._components['messenger'].send_by_logger(
                '\n\n[task]: %s\n[error]: %s\n\n[server]: %s' % (self._cfg['task_name'], msg, self._cfg['server']))
        except Exception as e:
            self._logger.critical('Failed to send error messages : %s' % e)

        if immediately_exit:
            sys.exit(msg)

    def _sleep(self, sleep_time=None):
        if not sleep_time:
            sleep_time = int(self._get_cfg('sleep_time', 30))

        self._logger.info('Sleeping ... (%ds)' % sleep_time)
        time.sleep(sleep_time)

    def _rest(self, rest_time=None):
        if not rest_time:
            rest_time = int(self._get_cfg('rest_time', 30))

        self._logger.info('Resting ... (%ds)' % rest_time)
        time.sleep(rest_time)

    def _get_cfg(self, key, default=None):
        ret = None

        if key in self._cfg:
            ret = self._cfg[key]

        if hasattr(self, '_excfg'):
            v = self._excfg.get(key)
            if v:
                ret = v

        return ret if ret else default
